Skip to content

Darling viewer: Query Store Regressions sub-tab (Dashboard parity)#1516

Merged
erikdarlingdata merged 2 commits into
devfrom
feature/darling-qs-regressions
Jul 14, 2026
Merged

Darling viewer: Query Store Regressions sub-tab (Dashboard parity)#1516
erikdarlingdata merged 2 commits into
devfrom
feature/darling-qs-regressions

Conversation

@erikdarlingdata

Copy link
Copy Markdown
Owner

What

Ports the Dashboard's Query Store Regressions grid to the Darling viewer as a new Queries sub-tab — the missing regressions GRID over the Query Store data Darling already collects. It ranks queries whose Query Store performance regressed (recent window vs. baseline).

Ported from the Dashboard: the SQL (GetQueryStoreRegressionsAsync → the report.query_store_regressions inline TVF, install/47_create_reporting_views.sql), the model (Dashboard/Models/QueryStoreRegressionItem.cs), and the grid (QueryStoreRegressionsDataGrid, QueryPerformanceContent.xaml).

Sub-tab placement (named-constant alignment)

Inserted at index 6, right after Query Store by Duration — matching the Dashboard's Query Store → Query Store Regressions adjacency and mirroring how PR #1515 inserted Current Active Queries. Every reference uses a NAMED constant, so only the tail shifts:

PerformanceTrends=0, ActiveQueries=1, CurrentActiveQueries=2, TopQueries=3,
TopProcedures=4, QueryStore=5, QueryStoreRegressions=6 (NEW), ExpensiveQueries=7, QueryHeatmap=8

The XAML <TabItem> order matches the constants exactly (verified: Performance Trends, Active Queries, Current Active Queries, Top Queries, Top Procedures, Query Store by Duration, Query Store Regressions, Expensive Queries, Query Heatmap).

The Postgres regression SQL

ViewerDataService.QueryStoreRegressions.cs adapts the TVF to Postgres against query_store_stats: two windowed CTEs (BASELINE = captures before the window; RECENT = the window), joined per (database, query_id), computing duration/CPU/IO regression %, execution-count-weighted additional_duration_ms, plan-count deltas, and a duration-driven severity band — keeping rows whose CPU regressed > 25% (the TVF's gate), ranked by added duration, TOP 50.

Faithful adaptations (all documented in the read's XML doc):

  • Baseline/recent split windows on collection_time (Darling's UTC window column), not the TVF's server_last_execution_time (Darling's local-wall-clock column — mixing it with UTC bounds would be a tz bug).
  • Recent query text = MAX(query_text) (Darling stores it decompressed; the TVF DECOMPRESS()es).
  • Ports the TVF's actual behavior (unbounded baseline, plain AVG, CPU-only gate) — the Dashboard C# caller's intent comment is stale and does not match what the TVF runs.

Parity wiring (sibling conventions)

  • Row VM reproduces every Dashboard grid column (Last Execution, Severity, Database, Query ID, Total Impact, Base/Recent Execs, Base/Recent Plans, Duration Δ%, Base/Recent Dur, CPU Δ%, Base/Recent CPU, I/O Δ%, Base/Recent Reads, Query Text).
  • DataGridFilterManager per Darling convention; [FEATURE] Add filter for databases(s) #1319 database filter honored ($4::text[]).
  • Double-click historyQueryStoreHistoryWindow (plan_id 0, query-scoped), mirroring the Dashboard grid and the sibling Query Store tab.
  • No slicer / comparison / plan surface — the read is a baseline-vs-recent contrast and carries no plan XML (like the Dashboard grid). The plan-less QueryGridRowStyle menu offers Copy Repro (functional from the query-text sample) + copy/export.

Tests (dotnet test Darling/Darling.Tests green — 2102 passed, 0 failed)

  • SQL string pins: base table, baseline/recent split on collection_time, CPU > 25% gate, added-duration ranking + LIMIT 50, severity thresholds, bigint/integer casts, unit conversion, [FEATURE] Add filter for databases(s) #1319 filter, PG positional dialect (added to the shared Queries dialect Theory).
  • Row display (raw server-clock), double-click key mapper (plan_id 0 / null gating), Copy Repro (plan-less), and a DARLING_TEST_PG-gated live round-trip proving baseline-vs-recent detection, the CPU gate, INNER-JOIN NEW-query exclusion, and the CRITICAL severity + added-duration math.

Darling-only — no Lite, Full Dashboard, or install/*.sql changes. Viewer + service build clean.

🤖 Generated with Claude Code

erikdarlingdata and others added 2 commits July 13, 2026 20:58
Port the Dashboard's Query Store Regressions grid to the Darling viewer as a new
Queries sub-tab, inserted at index 6 (after Query Store by Duration, matching the
Dashboard's Query Store -> Query Store Regressions adjacency). Every sub-tab index
uses a named constant, so Expensive Queries/Query Heatmap only shift.

- ViewerDataService.QueryStoreRegressions.cs: the Postgres port of the Dashboard's
  report.query_store_regressions TVF against query_store_stats -- baseline (before
  the window) vs recent (in-window) averages split on collection_time, CPU-regression
  > 25% gate, execution-count-weighted added-duration ranking, TOP 50, duration-driven
  severity bands; honors the #1319 database filter; row VM reproduces every column.
- Loader + switch case + constant (Queries.cs), FilterManager (Filters.cs), double-click
  history reusing QueryStoreHistoryWindow with plan_id 0 (History.cs), plan-less Copy
  Repro from the query-text sample (CopyExport.cs), and the XAML sub-tab (QueryGridRowStyle,
  no slicer/comparison -- matching the Dashboard grid and the sibling grid-only tabs).
- Tests: SQL string pins (base table, baseline/recent split, CPU gate, ranking/cap,
  severity, casts, DB filter, PG dialect), row display, key mapper, Copy Repro, and a
  gated live round-trip (baseline-vs-recent detection).

Darling-only: no Lite, Full Dashboard, or install/*.sql changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@erikdarlingdata erikdarlingdata merged commit ebcd32f into dev Jul 14, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant